package com.lincoln.framework.service;

import com.lincoln.framework.entity.SysAdmin;
import com.lincoln.framework.entity.SysAdminLog;
import com.lincoln.framework.hibernate.Page;
import com.lincoln.framework.hibernate.RestrictionsUtils;
import com.lincoln.framework.hibernate.SimpleHibernateTemplate;
import com.lincoln.framework.utils.ParameterChecker;
import com.lincoln.framework.utils.StringUtilsEx;
import org.hibernate.Criteria;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Disjunction;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.hibernate.sql.JoinType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 系统操作日志管理service
 * 
 * @author jared
 */
@Service
@Transactional
public class SysAdminLogService {
	
	@Autowired
	private SysAdminService sysAdminService;

	private SimpleHibernateTemplate<SysAdminLog, Integer> sysAdminLogDao;

	@Autowired
	public void setSessionFactory(SessionFactory sessionFactory) {
		sysAdminLogDao = new SimpleHibernateTemplate<SysAdminLog, Integer>(sessionFactory, SysAdminLog.class);
	}
	
	public Page<SysAdminLog> getSysAdminLogPage(Page<SysAdminLog> page) {
		Criteria c = sysAdminLogDao.createCriteria();
		Map<String, Object> queryMap = page.getQueryMap();
		
		c.createAlias("sysAdmin", "sysAdmin");
		String searchKey = (String)queryMap.get("searchKey");
		String searchVal = (String)queryMap.get("searchVal");
		if (!ParameterChecker.isNullOrEmpty(searchVal)) {
			if (!ParameterChecker.isNullOrEmpty(searchKey)) {
				c.add(RestrictionsUtils.ilike(searchKey, searchVal,
						MatchMode.ANYWHERE));
			} else {
				c.add(Restrictions.or(RestrictionsUtils.ilike("sysAdmin.name",
						searchVal, MatchMode.ANYWHERE), Restrictions.or(
						RestrictionsUtils.ilike("ipAddress", searchVal,
								MatchMode.ANYWHERE),
								RestrictionsUtils.ilike("content", searchVal,
										MatchMode.ANYWHERE))));
			}
		}
		page = sysAdminLogDao.findByCriteria(page, c);
		return page;
	}
	
	/**
	 * 日志写入
	 * 
	 */
	@Transactional
	public void log(String oper,int adminId,String ip) {
		SysAdminLog adminLog = new SysAdminLog();
		SysAdmin sysAdmin = sysAdminService.getSysAdminById(adminId);
		adminLog.setSysAdmin(sysAdmin);
		adminLog.setContent(oper);
		adminLog.setIpAddress(ip);
		adminLog.setOperateTime(new Date());
		sysAdminLogDao.save(adminLog);
	}
	
	/**
	 * 删除特定管理员的系统操作日志
	 */
	public void deleteSysAdminLogByAdminId (SysAdmin admin) {
		sysAdminLogDao.batchExecute("delete from SysAdminLog where sysAdmin.id = " + admin.getId());
	}
	
	/**
	 * 根据id获取系统管理员操作日志信息
	 * 
	 * @param id
	 * 
	 */
	public SysAdminLog getSysAdminLogById (int id) {
		return this.sysAdminLogDao.get(id);
	}
	
	/**
	 * 删除系统管理员操作日志信息
	 * 
	 * @param adminLog
	 *            void
	 */
	public void deleteSysAdminLog (SysAdminLog adminLog) {
		this.sysAdminLogDao.delete(adminLog);
	}
	
	/**
	 * 删除系统管理员操作日志信息
	 * 
	 * @param id
	 *            void
	 */
	public void deleteSysAdminLogById (int id) {
		this.sysAdminLogDao.delete(id);
	}
	
	/**
	 * 删除过去三个月的系统日志
	 */
	public void delerePreThreeMothLog() {
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		this.sysAdminLogDao.batchExecute("delete from SysAdminLog where operateTime <= '" + formatter.format(getPreThreeMonthDayDate()) + "'");
	}
	/**
	 * 得到上个月的月份（返回格式MM）
	 *
	 * @return
	 */
	public static java.util.Date getPreThreeMonthDayDate() {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.MONTH, -6);
		return new java.util.Date(calendar.getTime().getTime());
	}
	/**
	 * 查询出满足所有条件的系统日志
	 * @param searchKey 查询关键字
	 * @param searchVal 查询关键字的值
	 * @param order 排序方式
	 * @param orderBy 排序值
	 * @return
	 */
	public List<SysAdminLog> findAll(String searchKey, String searchVal, String order, String orderBy) {
		Criteria c = sysAdminLogDao.createCriteria();
		c.createAlias("sysAdmin", "sysAdmin", JoinType.LEFT_OUTER_JOIN);
		searchVal = searchVal == null ? searchVal : StringUtilsEx.escapeCriteriaLikeString(searchVal);
		if (!ParameterChecker.isNullOrEmpty(searchVal)) {
			Disjunction disjunction = Restrictions.disjunction();
			if (!ParameterChecker.isNullOrEmpty(searchKey)) {
				disjunction.add(Restrictions.like(searchKey, searchVal,
						MatchMode.ANYWHERE));
			} else {
				disjunction.add(Restrictions.or(RestrictionsUtils.ilike("sysAdmin.name",
						searchVal, MatchMode.ANYWHERE), Restrictions.or(
						RestrictionsUtils.ilike("ipAddress", searchVal,
								MatchMode.ANYWHERE),
								RestrictionsUtils.ilike("content", searchVal,
										MatchMode.ANYWHERE))));
			}
			c.add(disjunction);
		}
		if (!ParameterChecker.isNullOrEmpty(order) && !ParameterChecker.isNullOrEmpty(orderBy)){
			if (order.equals("desc")) {
				c.addOrder(Order.desc(orderBy));
			} else {
				c.addOrder(Order.asc(orderBy));
			}
		}else{
			c.addOrder(Order.desc("operateTime"));
		}
		return this.sysAdminLogDao.findByCriteria(c);
	}
}
